home *** CD-ROM | disk | FTP | other *** search
/ Sound Fx / Sound Fx.iso / Software / UNZIPED / MPW181-5 / _SETUP.1 / NeXT_obuffer.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-18  |  5.4 KB  |  213 lines

  1. /* NeXT_obuffer.cc
  2.  
  3.    Output buffer for NeXTStep copied from maplay 1.3b */
  4.  
  5. /*
  6.  *  @(#) obuffer_next.cc 1.1, last edit: 27 Oct 1994 17:20:53
  7.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  8.  *  @(#) Berlin University of Technology
  9.  *
  10.  *  NeXTStep class written at the end of June 1994 by
  11.  *  Pete French (pete@ohm.york.ac.uk) and Ian Stepehnson (ian@ohm.york.ac.uk)
  12.  *
  13.  *  This program is free software; you can redistribute it and/or modify
  14.  *  it under the terms of the GNU General Public License as published by
  15.  *  the Free Software Foundation; either version 2 of the License, or
  16.  *  (at your option) any later version.
  17.  *
  18.  *  This program is distributed in the hope that it will be useful,
  19.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  *  GNU General Public License for more details.
  22.  *
  23.  *  You should have received a copy of the GNU General Public License
  24.  *  along with this program; if not, write to the Free Software
  25.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27.  
  28. /*
  29.  *  New in maplay 1.3
  30.  */
  31.  
  32. // This code is messy. I'm not proud of it, but it does work.
  33. // Bear in mind that it is multi-threaded or it will make no
  34. // sense whatsoever. I apologise to any C++ programmers. All
  35. // the C++ I know was learnt from reading these files. Hence
  36. // it bears a striking resemblance to the Linux code...
  37. //
  38. // -Pete French.
  39.  
  40. #ifdef NeXT
  41.  
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <errno.h>
  46. #include <unistd.h>
  47. #include <fcntl.h>
  48. #include <signal.h>
  49. #include <sys/ioctl.h>
  50. #include <iostream.h>
  51.  
  52. #include "args.h"
  53. #include "header.h"
  54. #include "obuffer.h"
  55.  
  56. extern "Objective-C" {
  57. #import <appkit/appkit.h>
  58. #import <soundkit/NXPlayStream.h>
  59. #import <soundkit/NXSoundOut.h>
  60. #import <machkit/NXLock.h>
  61. };
  62.  
  63. float   NeXTObuffer::sample_rate;
  64. int     NeXTObuffer::chans;
  65.  
  66. extern  char *next_sound_host;    // from -H argument
  67.  
  68. static id song_lock_id, queue_lock_id;
  69. static id device_id, player_id;
  70. static int queue_length, drain_queue;
  71.  
  72.  
  73. @interface queue_counter:Object
  74. {
  75. }
  76. - soundStream:sender didCompleteBuffer:(int)tag;
  77. @end
  78.  
  79.  
  80. @implementation queue_counter
  81. - soundStream:sender didCompleteBuffer:(int)tag
  82. {
  83. [queue_lock_id lock];
  84. queue_length--;
  85. if(queue_length>MAX_QUEUE_LENGTH)
  86.  [queue_lock_id unlockWith:CANNOT_QUEUE];
  87. else
  88.  [queue_lock_id unlockWith:CAN_QUEUE];
  89. if((drain_queue) && (queue_length==0))
  90.  [song_lock_id unlock];
  91. return self;
  92. }
  93. @end
  94.  
  95.  
  96. NeXTObuffer::NeXTObuffer (uint32 number_of_channels, MPEG_Args *maplay_args)
  97. {
  98. #ifdef DEBUG
  99.   if (!number_of_channels || number_of_channels > MAXCHANNELS)
  100.   {
  101.     cerr << "NeXTObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n";
  102.     exit (1);
  103.   }
  104. #endif
  105.   sample_rate=(float)maplay_args->MPEGheader->frequency();
  106.   chans=number_of_channels;
  107.   if((sample_rate!=SND_RATE_HIGH) && (sample_rate!=SND_RATE_LOW))
  108.   {
  109.     cerr << "NeXT cannot play at sample rate " << sample_rate << "\n";
  110.     exit (1);
  111.   }
  112.   for (int i = 0; i < number_of_channels; ++i)
  113.     bufferp[i] = buffer + i;
  114.  
  115.   // get a device and player
  116.   device_id=[NXSoundOut alloc];
  117.   player_id=[NXPlayStream alloc];
  118.  
  119.   // initialise device and attach to player
  120.   if(next_sound_host!=NULL)
  121.     {
  122.      if([device_id initOnHost:next_sound_host]==nil)
  123.      {
  124.        cerr << "Could not get sound device on " << next_sound_host << "\n";
  125.        exit(1);
  126.      }
  127.     }
  128.   else
  129.     [device_id init];
  130.   [player_id initOnDevice:device_id];
  131.  
  132.   // setup the queue and queue counter
  133.   queue_lock_id=[[NXConditionLock alloc] initWith:CAN_QUEUE];
  134.   queue_length=0;
  135.   drain_queue=0;
  136.   [player_id setDelegate:[[queue_counter alloc] init]];
  137.  
  138.   //and start the player
  139.   song_lock_id=[[NXLock alloc] init];
  140.   [song_lock_id lock];
  141.   [player_id activate];
  142. }
  143.  
  144.  
  145. void NeXTObuffer::really_write_buffer (int16 **bp, int16 *bf)
  146. {
  147.   int length = (int)((char *)bp[0] - (char *)bf);
  148.   [queue_lock_id lockWhen:CAN_QUEUE];
  149.   queue_length++;
  150.   if(queue_length>MAX_QUEUE_LENGTH)
  151.    [queue_lock_id unlockWith:CANNOT_QUEUE];
  152.   else
  153.    [queue_lock_id unlockWith:CAN_QUEUE];
  154.   [player_id playBuffer:bf
  155.              size:length
  156.              tag:(int)1
  157.              channelCount:chans
  158.              samplingRate:sample_rate];
  159.   for (int i = 0; i < chans; ++i)
  160.     bp[i] = bf + i;
  161. }
  162.  
  163.  
  164. NeXTObuffer::~NeXTObuffer (void)
  165. {
  166.   NeXTObuffer::really_write_buffer(bufferp,buffer);
  167.   drain_queue=1;
  168.   [song_lock_id lock];
  169. }
  170.  
  171.  
  172. void NeXTObuffer::append (uint32 channel, int16 value)
  173. {
  174. #ifdef DEBUG
  175.   if (channel >= chans)
  176.   {
  177.     cerr << "illegal channelnumber in NeXTObuffer::append()!\n";
  178.     exit (1);
  179.   }
  180. #endif
  181.   if (bufferp[channel] - buffer >= OBUFFERSIZE)
  182.    NeXTObuffer::really_write_buffer(bufferp,buffer);
  183.   *bufferp[channel] = htons(value);
  184.   bufferp[channel] += chans;
  185. }
  186.  
  187. #ifdef SEEK_STOP
  188. void NeXTObuffer::clear_buffer(void)
  189. {
  190. }
  191.  
  192. void NeXTObuffer::set_stop_flag(void)
  193. {
  194. }
  195. #endif // SEEK_STOP
  196.  
  197. Obuffer *create_obuffer(MPEG_Args *maplay_args)
  198. {
  199.   Obuffer *buffer;
  200.  
  201.   enum e_mode mode = maplay_args->MPEGheader->mode();
  202.   enum e_channels which_channels = maplay_args->which_c;
  203.  
  204.   if (mode == single_channel || which_channels != both)
  205.     buffer = new NeXTObuffer (1, maplay_args);
  206.   else
  207.     buffer = new NeXTObuffer (2, maplay_args);
  208.  
  209.   return(buffer);
  210. }
  211.  
  212. #endif // NeXT
  213.